package custom.swing;

import java.io.File;
import java.util.Collection;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.KeyEvent;

import javax.swing.ListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.JTextField;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

public class FileListPanel extends JPanel {

    public static final long serialVersionUID = 1;
    private JToolBar toolBar = null;
    private JPanel toolBarPanel = null;
    protected JList list = null;
    private GenericListModel<File> listModel = null;
    private JScrollPane scrollPane = null;
    private JButton browseBtn = null;
    private JTextField editFld = null;
    private JFileChooser fileChooser = null;
    private boolean editVisible = false;
    private boolean validating = false;
    private boolean multiEnabled = false;
    private FileFilter fileFilter = null;
    private FileValidator fileValidator = null;
    private Frame owner = null;
    //private boolean contentsChanged = false;
    private int keyCount = 0;
    private int prevIndex = -1;
    private int curIndex = -1;
    private int selectionMode = FILES_ONLY;
    public static final int FILES_ONLY = JFileChooser.FILES_ONLY;
    public static final int DIRECTORIES_ONLY = JFileChooser.DIRECTORIES_ONLY;
    public static final int FILES_AND_DIRECTORIES = JFileChooser.FILES_AND_DIRECTORIES;

    /**
     * This is the default constructor
     */
    public FileListPanel() {
        super();
        initialize();
    }

    public FileListPanel(final Frame owner) {
        super();
        this.setOwner(owner);
        this.initialize();
    }

    public FileListPanel(final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.initialize();
    }

    public FileListPanel(final Collection<? extends File> c) {
        super();
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final FileFilter fileFilter) {
        super();
        this.setFileFilter(fileFilter);
        this.initialize();
    }

    public FileListPanel(final FileValidator fileValidator) {
        super();
        this.setFileValidator(fileValidator);
        this.initialize();
    }

    public FileListPanel(final int selectionMode) {
        super();
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.initialize();
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c) {
        super();
        this.setOwner(owner);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final FileFilter fileFilter) {
        super();
        this.setOwner(owner);
        this.setFileFilter(fileFilter);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final FileValidator fileValidator) {
        super();
        this.setOwner(owner);
        this.setFileValidator(fileValidator);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final int selectionMode) {
        super();
        this.setOwner(owner);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Collection<? extends File> c, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final FileFilter fileFilter, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.initialize();
    }

    public FileListPanel(final FileValidator fileValidator, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileValidator(fileValidator);
        this.initialize();
    }

    public FileListPanel(final int selectionMode, final boolean multiEnabled) {
        super();
        this.setFileSelectionMode(selectionMode);
        this.multiEnabled = multiEnabled;
        this.initialize();
    }

    public FileListPanel(final Collection<? extends File> c, final FileFilter fileFilter) {
        super();
        this.setFileFilter(fileFilter);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Collection<? extends File> c, final FileValidator fileValidator) {
        super();
        this.setFileValidator(fileValidator);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Collection<? extends File> c, final int selectionMode) {
        super();
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final FileFilter fileFilter, final FileValidator fileValidator) {
        super();
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
    }

    public FileListPanel(final FileFilter fileFilter, final int selectionMode) {
        super();
        this.setFileFilter(fileFilter);
        this.setFileSelectionMode(selectionMode);
    }

    public FileListPanel(final FileValidator fileValidator, final int selectionMode) {
        super();
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final FileFilter fileFilter, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final FileValidator fileValidator, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileValidator(fileValidator);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final int selectionMode, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileFilter fileFilter) {
        super();
        this.setOwner(owner);
        this.setFileFilter(fileFilter);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileValidator fileValidator) {
        super();
        this.setOwner(owner);
        this.setFileValidator(fileValidator);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final int selectionMode) {
        super();
        this.setOwner(owner);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final FileFilter fileFilter, final FileValidator fileValidator) {
        super();
        this.setOwner(owner);
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final FileFilter fileFilter, final int selectionMode) {
        super();
        this.setOwner(owner);
        this.setFileFilter(fileFilter);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final FileValidator fileValidator, final int selectionMode) {
        super();
        this.setOwner(owner);
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Collection<? extends File> c, final FileFilter fileFilter, final boolean multiEnabled) {
        super();
        this.setFileFilter(fileFilter);
        this.multiEnabled = multiEnabled;
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Collection<? extends File> c, final FileValidator fileValidator, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileValidator(fileValidator);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Collection<? extends File> c, final int selectionMode, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final FileFilter fileFilter, final FileValidator fileValidator, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.initialize();
    }

    public FileListPanel(final FileFilter fileFilter, final int selectionMode, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final FileValidator fileValidator, final int selectionMode, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Collection<? extends File> c, final FileFilter fileFilter, final FileValidator fileValidator) {
        super();
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Collection<? extends File> c, final FileFilter fileFilter, final int selectionMode) {
        super();
        this.setFileFilter(fileFilter);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Collection<? extends File> c, final FileValidator fileValidator, final int selectionMode) {
        super();
        this.setFileSelectionMode(selectionMode);
        this.setFileValidator(fileValidator);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final FileFilter fileFilter, final FileValidator fileValidator, final int selectionMode) {
        super();
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c,
            final FileFilter fileFilter, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c,
            final FileValidator fileValidator, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileValidator(fileValidator);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c,
            final int selectionMode, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileFilter fileFilter,
            final FileValidator fileValidator) {
        super();
        this.setOwner(owner);
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileFilter fileFilter,
            final int selectionMode) {
        super();
        this.setOwner(owner);
        this.setFileFilter(fileFilter);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileValidator fileValidator,
            final int selectionMode) {
        super();
        this.setOwner(owner);
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final FileFilter fileFilter, final FileValidator fileValidator,
            final int selectionMode) {
        super();
        this.setOwner(owner);
        this.setFileFilter(fileFilter);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Collection<? extends File> c, final FileFilter fileFilter,
            final FileValidator fileValidator, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Collection<? extends File> c, final FileFilter fileFilter,
            final int selectionMode, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Collection<? extends File> c, final FileValidator fileValidator,
            final int selectionMode, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final FileFilter fileFilter, final FileValidator fileValidator,
            final int selectionMode, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Collection<? extends File> c, final FileFilter fileFilter, final FileValidator fileValidator,
            final int selectionMode) {
        super();
        this.setFileValidator(fileValidator);
        this.setFileFilter(fileFilter);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileFilter fileFilter,
            final FileValidator fileValidator, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileFilter fileFilter,
            final int selectionMode, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileValidator fileValidator,
            final int selectionMode, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final FileFilter fileFilter, final FileValidator fileValidator,
            final int selectionMode, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileFilter fileFilter,
            final FileValidator fileValidator, final int selectionMode) {
        super();
        this.setOwner(owner);
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Collection<? extends File> c, final FileFilter fileFilter,
            final FileValidator fileValidator, final int selectionMode, final boolean multiEnabled) {
        super();
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public FileListPanel(final Frame owner, final Collection<? extends File> c, final FileFilter fileFilter,
            final FileValidator fileValidator, final int selectionMode, final boolean multiEnabled) {
        super();
        this.setOwner(owner);
        this.multiEnabled = multiEnabled;
        this.setFileFilter(fileFilter);
        this.setFileValidator(fileValidator);
        this.setFileSelectionMode(selectionMode);
        this.initialize();
        this.initListModel(c);
    }

    public void initListModel(final Collection<? extends File> c) {
        if (c != null && c.size() > 0) {
            listModel.addAll(c);
            // Add an empty index at the end so it can be double clicked to add an entry.
            appendSelection();
            list.setSelectedIndex(0);
        }
    }

    public void setInitBrowseDir(final File initBrowseDir) {
        if (initBrowseDir.exists() && initBrowseDir.isDirectory()) {
            fileChooser.setCurrentDirectory(initBrowseDir);
        }
    }

    private void addButtons(final JToolBar toolBar) {
        JButton button = null;
        ImageIcon icon = null;

        icon = createImageIcon("images/Add16.gif", "Add");
        button = new JButton(icon);
        button.setToolTipText("Add line(Insert)");

        button.addMouseListener(new java.awt.event.MouseAdapter() {

            public void mouseClicked(java.awt.event.MouseEvent e) {
                insertSelection();
            }
        });

        toolBar.add(button);

        //icon = createImageIcon("images/Delete16.gif", "Delete");
        icon = createImageIcon("images/delete_edit.gif", "Delete");
        button = new JButton(icon);
        button.setToolTipText("Delete line(Delete)");

        button.addMouseListener(new java.awt.event.MouseAdapter() {

            public void mouseClicked(java.awt.event.MouseEvent e) {
                deleteSelection();
            }
        });
        toolBar.add(button);

        icon = createImageIcon("images/Up16.gif", "Up");
        button = new JButton(icon);
        button.setToolTipText("Line up(Ctrl-Up)");

        button.addMouseListener(new java.awt.event.MouseAdapter() {

            public void mouseClicked(java.awt.event.MouseEvent e) {
                moveSelectionUp();
            }
        });
        toolBar.add(button);

        icon = createImageIcon("images/Down16.gif", "Down");
        button = new JButton(icon);
        button.setToolTipText("Line down(Ctrl-Down)");

        button.addMouseListener(new java.awt.event.MouseAdapter() {

            public void mouseClicked(java.awt.event.MouseEvent e) {
                moveSelectionDown();
            }
        });
        toolBar.add(button);
    }

    private void addFileToList(final int index, final File file) {
        listModel.remove(index);
        listModel.add(index, file);
        list.setSelectedIndex(index);
        hideEditFld();
        keyCount = 0;
        // Add a blank selection.
        insertSelection();
    //contentsChanged = true;

    // See if last file in list is a placeholder.
    //File lastFile = listModel.get(listModel.getSize() - 1);
    //if(lastFile.getPath() != " ")
    //{
            /* Add an empy field to the end so the user can add another file by clicking below the last
    visible file in the list. */
    //listModel.add(new File(" "));
    //}
    }

    protected void addListComponentListener() {
        if (list != null) {
            list.addComponentListener(new java.awt.event.ComponentAdapter() {

                public void componentResized(java.awt.event.ComponentEvent e) {
                    resizeEditFld();
                }
            });
        }
    }

    protected void addListKeyListener() {
        if (list != null) {
            list.addKeyListener(new java.awt.event.KeyAdapter() {

                public void keyPressed(java.awt.event.KeyEvent e) {
                    int keyCode = e.getKeyCode();
                    if (keyCode == KeyEvent.VK_INSERT) {
                        insertSelection();
                    } else if (keyCode == KeyEvent.VK_ESCAPE) {
                        hideEditFld();
                    } else if (keyCode == KeyEvent.VK_DELETE) {
                        deleteSelection();
                    } else if (keyCode == KeyEvent.VK_UP) {
                        if ((e.getModifiers()) == KeyEvent.CTRL_MASK) {
                            moveSelectionUp();
                        } else {
                            prevIndex = list.getSelectedIndex() - 1;
                            hideEditFld();
                        }
                    } else if (keyCode == KeyEvent.VK_DOWN) {
                        if ((e.getModifiers()) == KeyEvent.CTRL_MASK) {
                            moveSelectionDown();
                        } else {
                            prevIndex = list.getSelectedIndex() + 1;
                            hideEditFld();
                        }
                    }
                }
            });
        }
    }

    protected void addListMouseListener() {
        if (list != null) {
            list.addMouseListener(new java.awt.event.MouseAdapter() {

                public void mouseClicked(java.awt.event.MouseEvent e) {
                    int index = list.locationToIndex(e.getPoint());
                    if (index == prevIndex) {
                        showEditFld(index);
                    } else {
                        hideEditFld();
                        prevIndex = index;
                    }
                }
            });
        }
    }

    protected void addListSelectionListener() {
        if (list != null) {
            list.addListSelectionListener(new javax.swing.event.ListSelectionListener() {

                public void valueChanged(javax.swing.event.ListSelectionEvent e) {
                    boolean status = true;
                    int idx = list.getSelectedIndex();

                    /*
                    if(fileValidator != null)
                    {
                    File file = (File)list.getSelectedValue();
                    if((file != null) && (file.getPath() != " ") && (!fileValidator.isValid(file)))
                    {
                    status = false;
                    deleteSelection();
                    }
                    }
                     */
                    if (status) {
                        curIndex = idx;
                    }
                }
            });
        }
    }

    private void addListListeners() {
        addListComponentListener();
        addListKeyListener();
        addListMouseListener();
        addListSelectionListener();
    }

    public void clearFileList() {
        listModel.clear();
        prevIndex = curIndex = -1;
        keyCount = 0;
        list.setSelectedIndex(-1);
    }

    /** Returns an ImageIcon, or null if the path was invalid. */
    protected static ImageIcon createImageIcon(final String path, final String description) {
        java.net.URL imgURL = FileListPanel.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL, description);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

    public void deleteEmptyEntries() {
        if ((listModel != null) && (listModel.getSize() > 0)) {
            for (int i = 0; i < listModel.getSize();) {
                File file = listModel.get(i);
                if (file.getPath() == " ") {
                    listModel.remove(i);
                } else {
                    i++;
                }
            }
        }
    }

    /*
    public boolean didContentsChange()
    {
    return contentsChanged;
    }
     */
    private JButton getBrowseBtn() {
        if (browseBtn == null) {
            browseBtn = new JButton("...");
            browseBtn.addMouseListener(new java.awt.event.MouseAdapter() {

                public void mouseClicked(java.awt.event.MouseEvent e) {
                    if ((fileChooser.showDialog(owner, "Select")) == JFileChooser.APPROVE_OPTION) {
                        if (multiEnabled == true) {
                            File[] files = fileChooser.getSelectedFiles();
                            for (int i = 0; i < files.length; i++) {
                                if (validateFile(files[i])) {
                                    addFileToList(curIndex, files[i]);
                                }
                            }
                        } else {
                            File file = fileChooser.getSelectedFile();
                            if (validateFile(file)) {
                                addFileToList(curIndex, file);
                            }
                        }
                    }

                    if (editVisible) {
                        hideEditFld();
                    }
                }
            });

            browseBtn.setVisible(false);
        }
        return browseBtn;
    }

    private JTextField getEditFld() {
        if (editFld == null) {
            editFld = new JTextField();
            editFld.setVisible(false);
            editFld.addKeyListener(new java.awt.event.KeyAdapter() {

                public void keyPressed(java.awt.event.KeyEvent e) {
                    int keyCode = e.getKeyCode();
                    if ((keyCode == KeyEvent.VK_ENTER) && (keyCount > 0)) {
                        String name = editFld.getText().trim();
                        File file = new File(name);
                        validating = true;
                        if (validateFile(file)) {
                            addFileToList(curIndex, file);
                        }
                        validating = false;
                    } else if (keyCode == KeyEvent.VK_ESCAPE) {
                        hideEditFld();
                        keyCount = 0;
                    }
                }

                public void keyTyped(java.awt.event.KeyEvent e) {
                    keyCount = editFld.getText().length();
                }
            });

            editFld.addFocusListener(new java.awt.event.FocusListener() {

                public void focusGained(java.awt.event.FocusEvent e) {
                }

                public void focusLost(java.awt.event.FocusEvent e) {
                    if (keyCount > 0) {
                        String name = editFld.getText().trim();
                        File file = new File(name);
                        if (!validating && validateFile(file)) {
                            addFileToList(prevIndex, file);
                        }
                    }
                }
            });
        }
        return editFld;
    }

    public JFileChooser getFileChooser() {
        return fileChooser;
    }

    private GenericListModel getGenericListModel() {
        if (listModel == null) {
            listModel = new GenericListModel<File>();
        }
        return listModel;
    }

    /**
     * This method initializes list 
     *  
     * @return javax.swing.JList    
     */
    private JList getList() {
        if (list == null) {
            list = new JList(getGenericListModel());
            list.setDragEnabled(true);
            list.setTransferHandler(new FileListTransferHandler());
            list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
            list.add(getEditFld());
            list.add(getBrowseBtn());

            addListListeners();
        }
        return list;
    }

    public ListModel getListModel() {
        // Before returning the listModel, see if its last entry is just a place holder. If it is, remove it.
        int size = listModel.getSize();
        if (size > 0 && listModel.get(size - 1).toString().equals(" ")) {
            listModel.remove(size - 1);
        }
        return listModel;
    }

    private void moveSelectionUp() {
        int index = list.getSelectedIndex();
        if (index > 0) {
            hideEditFld();
            File file = listModel.get(index);
            // Don't move them if either file is just a place holder.
            if (file.getPath() != " " && listModel.getElementAt(index - 1).getPath() != " ") {
                listModel.add(index - 1, file);
                listModel.remove(index + 1);
                list.setSelectedIndex(index - 1);
                prevIndex = index - 1;
            }
        }
    }

    public void setListModel(final GenericListModel<File> listModel) {
        list.setModel(listModel);
        this.listModel = listModel;
    }

    protected int getPrevIndex() {
        return prevIndex;
    }

    private JScrollPane getScrollPane() {
        if (scrollPane == null) {
            scrollPane = new JScrollPane(getList());
        }
        return scrollPane;
    }

    private JToolBar getToolBar() {
        if (toolBar == null) {
            toolBar = new JToolBar();
            addButtons(toolBar);
        }

        return toolBar;
    }

    private JPanel getToolBarPanel() {
        if (toolBarPanel == null) {
            toolBarPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
            toolBarPanel.add(getToolBar());
        }
        return toolBarPanel;
    }

    protected void hideEditFld() {
        if (editVisible) {
            editFld.setVisible(false);
            browseBtn.setVisible(false);
            editVisible = false;
        }
    }

    private JFileChooser initFileChooser() {
        if (fileChooser == null) {
            fileChooser = new JFileChooser();
            fileChooser.setFileSelectionMode(this.selectionMode);
            if (fileFilter != null) {
                fileChooser.setFileFilter(fileFilter);
            }
            fileChooser.setMultiSelectionEnabled(multiEnabled);
        }
        return fileChooser;
    }

    /**
     * This method initializes this
     * 
     * @return void
     */
    private void initialize() {
        this.setLayout(new BorderLayout());
        this.add(getToolBarPanel(), BorderLayout.NORTH);
        this.add(getScrollPane(), java.awt.BorderLayout.CENTER);
        this.initFileChooser();

    /*
    this.addComponentListener(new java.awt.event.ComponentAdapter()
    {
    public void componentResized(java.awt.event.ComponentEvent e)
    {
    System.out.println("FileListPanel size: " + getSize());
    //setPreferredSize(getSize());
    }
    });
     */

    }

    private void resizeEditFld() {
        int index = list.getSelectedIndex();
        if ((index != -1) && (editVisible)) {
            Rectangle r = list.getCellBounds(index, index);
            Dimension size = new Dimension(r.width - 30, r.height);
            editFld.setSize(size);
            editFld.setPreferredSize(size);
            browseBtn.setLocation(r.width - 30, browseBtn.getLocation().y);
        }
    }

    public void setOwner(final Frame owner) {
        this.owner = owner;
    }

    public void setFileFilter(final FileFilter fileFilter) {
        this.fileFilter = fileFilter;
    }

    public void setFileSelectionMode(final int selectionMode) {
        this.selectionMode = selectionMode;
    }

    public void setFileValidator(final FileValidator fileValidator) {
        this.fileValidator = fileValidator;
    }

    protected void setPrevIndex(final int prevIndex) {
        this.prevIndex = prevIndex;
    }

    protected void showEditFld(int index) {
        if (!editVisible) {
            if (index == -1) {
                index = 0;
                if (listModel.getSize() == 0) {
                    listModel.add(index, new File(" "));
                }
                list.setSelectedIndex(index);
            }

            Rectangle r = list.getCellBounds(index, index);
            editFld.setBounds(0, r.y, r.width - 30, r.height);
            browseBtn.setBounds(r.width - 30, r.y, 30, r.height);

            File file = null;
            if (listModel.getSize() > 0) {
                file = (File) list.getSelectedValue();
                editFld.setText(file.toString());
            } else {
                editFld.setText("");
            }

            prevIndex = index;
            // Put a slight delay before setting to visible
            //try{ Thread.sleep(1000); }
            //catch(InterruptedException e) {}
            editFld.setVisible(true);
            browseBtn.setVisible(true);
            editVisible = true;
        }
    }

    /**
     * 
     */
    private void moveSelectionDown() {
        int index = list.getSelectedIndex();
        if (index > -1 && index < listModel.getSize() - 1) {
            hideEditFld();
            File file = listModel.get(index);
            // Don't move them if either file is just a place holder.
            if (file.getPath() != " " && listModel.getElementAt(index + 1).getPath() != " ") {
                listModel.remove(index);
                listModel.add(index + 1, file);
                list.setSelectedIndex(index + 1);
                prevIndex = index + 1;
            }
        }
    }

    /**
     * 
     */
    private void deleteSelection() {
        int index = list.getSelectedIndex();
        if (index != -1) {
            listModel.remove(index);
            if (index > listModel.getSize() - 1) {
                index--;
                prevIndex = index;
            }
            list.setSelectedIndex(index);
        }
    }

    /**
     * 
     */
    private void insertSelection() {
        if (!editVisible) {
            int index = list.getSelectedIndex();
            // Make sure we do not go out of the bounds of the listModel array.
            int size = listModel.getSize();
            if (size <= index) {
                index = size - 1;
            }

            listModel.add(index + 1, new File(" "));
            list.setSelectedIndex(index + 1);
            showEditFld(index + 1);
        }
    }

    private void appendSelection() {
        int size = listModel.getSize();
        listModel.add(size, new File(" "));
    }

    private boolean validateFile(final File file) {
        boolean status = true;

        if (fileValidator != null) {
            status = fileValidator.isValid(file);
        }
        return status;
    }
}
